package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;

/**
 * @author ：石破天
 * @date ：Created in 2022年12月17日
 * @description ：
 * @version: 1.0
 */
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired // 从spring根据类型找对象！！
    private EmployeeService employeeService;
    /*
       写一个方法处理登录的请求？
          登录的逻辑该怎么处理！！！！


        写的返回值是对象，
        但实际上  返回给前端的不是对象 ！！！！！！
             返回的是  对象--json  格式数据！！！！
               @ResponseBody
               底层 默认是jackson  它的 对象转成json的方法
                   但是这个方法底层 完成 对象-->json
                     需要用到对象的  get方法


               @RequestBody
                   前端 json--->对象
                     底层也是jackson
                        用到的是对象的 set 方法
     */
    @PostMapping("/login")
    public R<Employee> login(@RequestBody Employee employee, HttpSession session){// username admin
        log.info("登录的用户信息:"+employee);
        //1:对页面提交的密码进行加密
        String password = employee.getPassword();
        password= DigestUtils.md5DigestAsHex(password.getBytes());//md5加密
        //2:根据页面提交的用户名查询数据库 查询用户
        // mp里面方法怎么用？ 查官网   select * from employee where username=?
        //  T getOne(Wrapper queryWrapper)
        // 如果是带条件的查询 需要先构建 queryWrapper对象/lambdaQueryWrapper对象
        //    封装咱们 where 后面 条件的  哪个对象
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        // LambdaQueryWrapper 可以解决硬编码
        wrapper.eq(Employee::getUsername,employee.getUsername());
                //  where username = “admin”
        Employee emp = employeeService.getOne(wrapper);//select * from employee where username = “admin”

        //3:查询到的用户如果是null 说明是不存在的 没有必要继续
        //  return R.error("用户名或密码不存在");
        if(emp==null){//说明用户不存在
            return R.error("用户名或密码不正确！");
        }
        //4: 执行到这里有该用户，再进行密码比对，
        // 密码不正确   没有必要继续
        if(!emp.getPassword().equals(password)){
            return R.error("用户名或密码不正确！");
        }
       // 5: 密码正确 还得检查 用户是否是禁用的
       // 若果是禁用的 那就返回 R.error("已经被禁用了")
        if(emp.getStatus()==0){//禁用了
           return R.error("已经被禁用了,解禁给管理员 康佳 转账1000000");
        }
       // 6:登录成功  把登录的员工用户id存储session中。
        session.setAttribute("employee",emp.getId());//存储id到session  第三天有用！！第二天也有用！
       // 完成成功响应。
        log.info("用户登录成功！！！！也完成session存储");
        return R.success(emp);

    }

    /*
      退出登录
     */
    @PostMapping("/logout")
    public R<String> logout(HttpSession session){

        // 把员工的登录信息  从 域中删除掉
        session.removeAttribute("employee");
       // 我们只要完成 相应的响应  由前端 完成哪些页面跳转！！！
        return R.success("退出登录");
    }


    /*
    保存员工信息
     */
    @PostMapping
    public R<String> save(@RequestBody Employee employee,HttpSession session){
        log.info("新建员工的基本信息:{}",employee);
        log.info("新建员工信息:"+employee);
        //前端传递来的只有五个数据  说明employee完整
        // 1: 完成employee 其他属性的封装
        // 2: 设置密码  设置加密密码存数据库
        String password = DigestUtils.md5DigestAsHex("123456".getBytes());
        employee.setPassword(password);
//        //3:  设置创建时间 和更新时间
//        LocalDateTime now = LocalDateTime.now();//获取当前时间
//        employee.setUpdateTime(now);
//        employee.setCreateTime(now);
//        //4: 设置修改人 创建人  就是登录人 id
//        Long empId = (Long)session.getAttribute("employee");
//        employee.setCreateUser(empId);
//        employee.setUpdateUser(empId);

        //5: 字段补全后 通过 employeeService 完成数据的保存
        employeeService.save(employee);

       //6: 响应前端
        return R.success("添加用户成功");

    }

    /**
     * 分页查询
     * @param page  页码
     * @param pageSize 每页显示条数
     * @param name   模糊查询的关键字
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){
      //1:构建 分页构造器 创建page对象 传入页码和每页显示条数
        Page<Employee> pageInfo = new Page<>(page,pageSize);
      //2:构建 条件构造器 querywrapper
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
      //3:拼接条件
        //这个name条件一定有吗？
       if(name!=null && name.length()>0){//name条件有东西就拼
           wrapper.like(Employee::getName,name);//where name like 传递的name值

       }
       // 在开发查询的时候会有一个潜规则  稍微说一下 业务中不会明说的
        // 如果 数据有排序的规则 按照排序规则查询 没有排序规则 更新时间查询
        wrapper.orderByDesc(Employee::getUpdateTime);//时间降序 最新在上面
        // ORDER BY update_time DESC

      //4: 执行分页查询操作
        employeeService.page(pageInfo,wrapper);// 方法 limit  count
        // 底层会把查询到的数据 设置到 pageInfo中

      //5:把Page对象封装到R中 完成返回
        return R.success(pageInfo);
    }

    /**
     *  编辑员工功能呢
     */
    @PutMapping
    public R<String> update(@RequestBody Employee employee,HttpSession session){
        log.info("要编辑的员工数据:{}",employee);
        log.info("要编辑的员工的id是:"+employee.getId());
        System.out.println("Controller处理器update中 当前的线程id:"+Thread.currentThread().getId());

        // 需要service 完成根据id更新
        // 查看 官网的方法
        // 根据 ID 选择修改
     //    boolean updateById(T entity);
        employeeService.updateById(employee);

        return R.success("员工信息修改成功");
    }

    /**
     * 根据id查询员工信息
     *      /employee/1604375363542974466
     *      参数在路径上
     *          XxxMapping...中 要用 /{} 形式去表达
     *            比如 “/{id}”
     *         在参数位置
     *           @PathVariable("id")
     */
    @GetMapping("/{id}")
    public R<Employee> getById(@PathVariable Long id){
        log.info("需要查询的id是:"+id);
        // 找到service 根据id查询
        Employee employee = employeeService.getById(id);

        return R.success(employee);
    }
}
